package com.zc.study.pay.wechat;

import com.alibaba.fastjson.JSON;
import com.zc.study.pay.PayCommonUtil;
import com.zc.study.pay.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.*;

public class Wechat {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 拉取微信预付单
     */
    public BaseResult<Orders> getWXPay(BaseRequest<Orders> baseRequest)
    {
        BaseResult<Orders> baseResult = new BaseResult<>();
        Orders orders = baseRequest.getData();
        Double price = orders.getOrderAmount();
        if (price <= 0) // 防止抓包修改订单金额造成损失
        {
            baseResult.setState(-999);
            baseResult.setMsg("付款金额错误!");
            baseResult.setSuccess(false);
            return baseResult;
        }
        try
        {
            SortedMap<Object, Object> parameters = PayCommonUtil.getWXPrePayID(); // 获取预付单，此处已做封装，需要工具类

            TravelFly travelFly = new TravelFly(); // 商品对象
            travelFly.setId(orders.getProductId());
//            travelFly = travelFlyMapper.selectById(travelFly);//从数据库查出产品的相关信息
//            travelFly.setBusinesser(businesserMapper.selectByPrimaryKey(travelFly.getBusinesserId()));//从数据库中查出商家信息
            orders.setTravelFly(travelFly);
            parameters.put("body", "xxx产品-" + travelFly.getProductName());

           // parameters.put("spbill_create_ip", this.request.getRemoteAddr());//获取IP地址.到时候测试修改
            parameters.put("out_trade_no", orders.getId() + PayCommonUtil.getDateStr()); // 订单id这里我的订单id生成规则是订单id+时间
            parameters.put("total_fee", "1"); // 测试时，每次支付一分钱，微信支付所传的金额是以分为单位的，因此实际开发中需要x100
            // parameters.put("total_fee", orders.getOrderAmount()*100+""); // 上线后，将此代码放开

            // 设置签名
            String sign = PayCommonUtil.createSign("UTF-8", parameters);
            parameters.put("sign", sign);
            // 封装请求参数结束
            String requestXML = PayCommonUtil.getRequestXml(parameters); // 获取xml结果
            logger.debug("封装请求参数是：" + requestXML);
            // 调用统一下单接口
            String result = PayCommonUtil.httpsRequest(PayCommonUtil.NOTIFY_URL, "POST",
                    requestXML);
            logger.debug("调用统一下单接口：" + result);
            SortedMap<Object, Object> parMap = PayCommonUtil.startWXPay(result);
            logger.debug("最终的map是：" + parMap.toString());
            if (parMap != null)
            {
                orders.setWxPayOrderString(JSON.toJSONString(parMap));
                baseResult.setData(orders);
            } else
            {
                baseResult.setState(-999);
                baseResult.setMsg("支付出现异常，请稍后重试!");
                baseResult.setSuccess(false);
            }
        } catch (Exception e)
        {
            e.printStackTrace();
            baseResult.setState(-999);
            baseResult.setMsg("程序异常!");
            baseResult.setSuccess(false);
            logger.error(e.getMessage());
        }
        return baseResult;
    }


    /**
     * 微信异步通知
     */
    public void wxNotify(HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        String result = PayCommonUtil.reciverWx(request); // 接收到异步的参数
        Map<String, String> m = new HashMap<String, String>();// 解析xml成map
        if (m != null && !"".equals(m))
        {
            m = (Map<String, String>) XmlUtil.fromXML(result,Map.class);
        }
        // 过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext())
        {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);
            String v = "";
            if (null != parameterValue)
            {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }
        // 判断签名是否正确
        String resXml = "";
        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams))
        {
            if ("SUCCESS".equals((String) packageParams.get("return_code")))
            {
                // 如果返回成功
                String mch_id = (String) packageParams.get("mch_id"); // 商户号
                String out_trade_no = (String) packageParams.get("out_trade_no"); // 商户订单号
                String total_fee = (String) packageParams.get("total_fee");
                // String transaction_id = (String)
                // packageParams.get("transaction_id"); // 微信支付订单号
                // 查询订单 根据订单号查询订单
                String orderId = out_trade_no.substring(0, out_trade_no.length() - PayCommonUtil.TIME.length());
               // Orders orders = ordersMapper.selectByPrimaryKey(Integer.parseInt(orderId));

                // 验证商户ID 和 价格 以防止篡改金额
                //if (PayCommonUtil.WECHAT_MCH_ID.equals(mch_id) && orders != null
                if (PayCommonUtil.WECHAT_MCH_ID.equals(mch_id)
                    // &&
                    // total_fee.trim().toString().equals(orders.getOrderAmount())
                    // // 实际项目中将此注释删掉，以保证支付金额相等
                        )
                {
                    /** 这里是我项目里的消费状态
                     * 1.待付款=0 2.付款完成=1
                     * 3.消费成功=2
                     * 4.取消=-1
                     * 5.发起退款=-2
                     * 6.退款成功=-3
                     * 7.退款失败=3（由于商户拒绝退款或其他原因导致退款失败）
                     */
//                    insertWxNotice(packageParams);
//                    orders.setPayWay("1"); // 变更支付方式为wx
//                    orders.setOrderState("1"); // 订单状态为已付款
//
//                    ordersMapper.updateByPrimaryKeySelective(orders); // 变更数据库中该订单状态
//                    // ordersMapper.updatePayStatus(Integer.parseInt(orderId));
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                            + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                } else
                {
                    resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                            + "<return_msg><![CDATA[参数错误]]></return_msg>" + "</xml> ";
                }
            } else // 如果微信返回支付失败，将错误信息返回给微信
            {
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[交易失败]]></return_msg>" + "</xml> ";
            }
        } else
        {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[通知签名验证失败]]></return_msg>" + "</xml> ";
        }

        // 处理业务完毕，将业务结果通知给微信
        // ------------------------------
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }
}
